#!/bin/sh

#  Name:        locate-computer
#  Version:     0.3
#  Depends:		curl, GeoIP

#  Purpose:		Locate georeferential position (City)
#               of a given computer. This is both
#               useful for weather scripts automation
#               and somewhat for security in case of
#               steal or loss.
#  NOTES:       Cache granularity is one day. If it's
#               necessary to improve this, drop me an
#               email.
#  Goal:        Try to get results in many different
#  TODO:        This is just a DRAFT and almost a
#               complete mess. Wait a little if you
#               want to see a cleanup, nerd.
#               possible scenarios.
#  Creation:   	Mon Oct 25 2010
#  Modified:	Thu Oct 28 2010, 03:54:31
#  Insects:		What species? No bugs known,yet.
#
#  Feel free to contact me at:
#  <http://linuxrules.googlecode.com>
#  in case of bugs, updates, proposals or comments

#  Copyright (C) 2010 Mario García H.
#
#  "THE BEER-WARE LICENSE" (Revision 42):
#  <code933k (AT) gmail> wrote this file. As long as you retain
#  this notice you can do whatever you want with this stuff.
#
#  If we meet some day, and you think this stuff is worth it,
#  you can buy me a BEER in return, Mario García H.
#
#  THIS IS FREE SOFTWARE PROVIDED AS-IS
#  THERE IS NO WARRANTY, TO THE EXTENT PERMITTED BY LAW.

LAST_LOC=
LAST_IP=
CURL=

case $VERBOSE in
    true )
    echo "Locate Computer: [VERBOSE]"
    echo --------------------------
    echo
    ;;
    * ) VERBOSE=
    ;;
esac

geo_error() {
    printf "\033[01;31mERROR:\033[m\n"
    echo $*
    exit 1
}

# We depend on curl so that we don't have to rely in
# gawk. This makes this script a little system agnostic
CURL="$(whereis curl | cut -d ' ' -f 2)"
test  -x "$CURL"    || geo_error "Cannot find curl program"

# Accept external variables GEOLC and GEOLD if required
test  -z "$GEOLD"   && GEOLD="$HOME/.local/share/3dparty/"
test  -z "$GEOLC"   && GEOLC="$GEOLD/GeoLiteCity.dat"
mkdir -p "$GEOLD"   2>/dev/null
test  -d "$GEOLD"   || geo_error "GEOLD directory not specified nor readable"

# Check whether GeoLiteCity.dat is currently installed.
if ! test -r "$GEOLC"
then
    echo Cannot read $GEOLC
    echo ------------------------------
    echo You must install this file in
    echo order to locate this computer.
    echo -----------------------------
    echo Bye.
    echo
    exit 1
fi

advice_too_fast() {
cat <<EOF
If this is an automated job, you are updating too fast.
Please consider an enterprise plan or just correct this
issue:
---------
TIPS:
1. Regular folks need just an update once in a while.
i.e., one to four times a day or week.
EOF
return 0
}


show_getip() {
# Show last IP address retrieved.
# This is sort of offline failproof
    test -n "$VERBOSE" && echo \* issued show_getip
    NUMBER=0

    for ip in ${GEOLD}ipaddress-*
    do
        LAST_IP="$(cat $ip)"

        if test -n "$VERBOSE"
        then
            NUMBER=$(expr $NUMBER + 1)
            echo "- Checking show_getip register $NUMBER"
            echo "${ip}: $LAST_IP"
        fi

        if test -z "$LAST_IP"
        then
            geo_error "Cannot find any IP previously retrieved"
        fi
    done

    echo
    return 0
}

show_geolc() {
# Show last IP address retrieved.
# This is sort of offline failproof
    test -n "$VERBOSE" && echo \* issued show_geolc
    NUMBER=0

    for loc in ${GEOLD}geoip-location-*
    do
        LAST_LOC="$(cat $loc)"

        if test -n "$VERBOSE"
        then
            NUMBER=$(expr $NUMBER + 1)
            echo "- Checking show_geolc register $NUMBER"
            echo "${loc}: $LAST_LOC"
        fi
        
        test -z "$LAST_LOC" && return 1
    done

    echo
    return 0
}

get_ip() {
    test -n "$VERBOSE" && echo \* issued get_ip
    $CURL -f -s 'http://echoip.com' > "$GEOLD/ipaddress-$(date '+%y%m%d')"

    # just to make sure nothing went
    # wrong in the shell interpreter
    return $?
}

geo_ip() {
    local GEOIP=''

    test -n "$VERBOSE" && echo \* issued geo_ip
    GEOIP="$(whereis geoiplookup| cut -d ' ' -f 2)"

    if test -x "$GEOIP" 
    then
        show_getip

        case "$VERBOSE" in
            true )
            echo $GEOIP -f "$GEOLC" "$LAST_IP" '>' \
            "${GEOLD}geoip-location-$(date '+%y%m%d')"
            ;;
        esac

        # $GEOIP -f "$GEOLC" "$LAST_IP" > "${GEOLD}geoip-location-$(date '+%y%m%d')"

        case $? in
            0 ) ;;
            * )
            advice_too_fast
            geo_error "There was an error while retrieving your location."
            ;;
        esac

    else
        echo You must install geoiplookup firstly
        echo in order to use this program with
        echo your IP geolocation.
        echo
        echo It is usually named GeoIP, but
        echo remember we want the library with
        echo binary helpers. Not perl version.
        echo
        echo If you don\'t know what I am talking
        echo about, use linuxrules weather helper
        echo in no dynamic mode. -h for help.
        echo
        exit 1
    fi

    case "$VERBOSE" in
        true )
        echo
        echo Will use geo_ip register: \
        "${GEOLD}geoip-location-$(date '+%y%m%d')"
        cat "${GEOLD}geoip-location-$(date '+%y%m%d')"
        echo
        ;;
    esac

    return 1
}

##########################################
# TRANSFORMERS™: PREPARE AND ROLL OUT! ™ #
##########################################

# An IP is extrictly necessary the 1st time.
if test -z "$LAST_IP"
then
    get_ip \
    || geo_error "Cannot get an IP address. \\
    TIP: Is this your 1st time? Are you connected to Internet?"
else
    get_ip
fi

geo_ip

exit 0

